package org.lychie.controller;

import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import static org.springframework.web.bind.annotation.RequestMethod.*;

/**
 * 注解 @RequestMapping 标注在类级别上的示例
 * 
 * @author Lychie Fan
 * 
 * <http://lychie.github.io 2015-03-20>
 */
@Controller
@RequestMapping("/class-level-mapping")
public class ClassLevelMappingController {

	@RequestMapping(method = GET)
	public String list() {
		return "class-level-mapping/list";
	}
	
	@RequestMapping(value = "/pathname", method = GET)
	public String mappedByPathname(Model model) {
		model.addAttribute("message", "mapped by /pathname");
		return "class-level-mapping/result";
	}

	@RequestMapping(value = "/pathname/*", method = GET)
	public String mappedByPathnamePattern(Model model) {
		model.addAttribute("message", "mapped by /pathname/*");
		return "class-level-mapping/result";
	}

	@RequestMapping(value = "/pathname/*.html", method = GET)
	public String mappedByPathnameExtension(Model model) {
		model.addAttribute("message", "mapped by /pathname/*.html");
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/parameter", method = GET, params = "param")
	public String mappedByParameter(Model model, String param) {
		model.addAttribute("message", "the param is " + param);
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/parameter", method = GET, params = "!param")
	public String mappedByParameterNegation(Model model) {
		model.addAttribute("message", "mapped by /parameter, not supposed param");
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/argument", method = GET, params = "param=1")
	public String mappedByParameterEquals(Model model) {
		model.addAttribute("message", "mapped by /argument, only param = 1");
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/argument", method = GET, params = "param!=1")
	public String mappedByParameterNotEquals(Model model) {
		model.addAttribute("message", "mapped by /argument, only param != 1");
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/header", method = POST, headers = "content-type=application/*")
	public String mappedByHeader(Model model) {
		model.addAttribute("message", "mapped by /header + presence of header");
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/header", headers = "!content-type")
	public String mappedByHeaderNegation(Model model) {
		model.addAttribute("message", "mapped by /header + absence of header");
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/produce", method = GET, produces = "application/json")
	public @ResponseBody Person mappedByProduce() {
		return new Person(1001, "Lychie Fan");
	}
	
	@RequestMapping(value = "/consume", method = POST, consumes = "application/json")
	public String mappedByConsume(@RequestBody Person person) {
		System.out.println("person = " + person);
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/foo/{bar}", method = GET)
	public String mappedByUriTemplate(Model model, @PathVariable String bar) {
		model.addAttribute("message", bar);
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/food/{name}/{kind}", method = GET)
	public String mappedByUriTemplate(Model model, @PathVariable("name") String foodName, @PathVariable String kind) {
		model.addAttribute("message", foodName + ", " + kind);
		return "class-level-mapping/result";
	}
	
	@RequestMapping(value = "/{filename:[a-z-_]+}{extension:\\.[a-z]+}", method = GET)
	public String mappedByRegular(Model model, @PathVariable String filename, @PathVariable String extension) {
		model.addAttribute("message", filename + extension);
		return "class-level-mapping/result";
	}
	
	public static class Person {
		
		private int id;
		private String name;
		
		public Person() {
			
		}
		
		public Person(int id, String name) {
			this.id = id;
			this.name = name;
		}

		public int getId() {
			return id;
		}

		public void setId(int id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		@Override
		public String toString() {
			return "[ id : " + id + ", name : " + name + " ]";
		}
		
	}
	
}